//   Copyright 2009 Pyxis Technologies
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//

using System;
using Pyxis.FluentSelenium.Locator;
using Selenium;

namespace Pyxis.FluentSelenium.Tester
{
    public class ContentTester
    {
        private readonly ISelenium selenium;
        private readonly ElementLocator locator;

        public ISelenium Selenium
        {
            get { return selenium; }
        }

        public ILocator Locator
        {
            get { return locator; }
        }

        internal ContentTester(ISelenium selenium)
        {
            this.selenium = selenium;
            locator = ElementLocator.WithXpath("");
        }

        public ContentTester(ISelenium selenium, string locator)
        {
            this.selenium = selenium;
            this.locator = ElementLocator.WithXpath(locator);
        }

        public ContentTester(ElementLocator locator, ContentTester rootTester)
        {
            this.locator = locator;
            this.selenium = rootTester.Selenium;
        }

        public void ShouldSee(ILocator childLocator)
        {
            childLocator.Append(locator);
            var elementFound = Selenium.IsVisible(childLocator.ToString());
            if (!elementFound)
                throw ConditionError.ElementShouldBeVisible(childLocator);
        }

        public void ShouldSee(string expectedText)
        {
            var acctualText = Selenium.GetText(Locator.ToString());

            Assert.ContentMatch(expectedText, acctualText, Locator);
        }

        public void ShouldSee(ILocator childLocator, string expectedText)
        {
            childLocator.Append(locator);
            var acctualText = Selenium.GetText(childLocator.ToString());

            Assert.ContentMatch(expectedText, acctualText, childLocator);
        }

        public void ShouldNotSee(ILocator childLocator)
        {
            childLocator.Append(locator);
            var elementIsVisible = Selenium.IsVisible(childLocator.ToString());

            Assert.ElementIsNotVisible(elementIsVisible, childLocator);
        }

        public void ShouldSee(IContentValidator childLocator)
        {
            childLocator.Validate(this);
        }

        public void WaitFor(IWaitCondition waitCondition)
        {
            waitCondition.Wait(this);
        }

        #region Steps
        public ContentTester For(ElementLocator childLocator)
        {
            childLocator.Append(locator);
            return new ContentTester(childLocator, this);
        }

        public ComboboxTester For(ComboboxLocator childLocator)
        {
            childLocator.Append(locator);
            return new ComboboxTester(childLocator, this);
        }

        public InputTester For(InputLocator childLocator)
        {
            childLocator.Append(locator);
            return new InputTester(childLocator, this);
        }

        public ButtonTester For(ButtonLocator buttonLocator)
        {
            buttonLocator.Append(locator);
            return new ButtonTester(buttonLocator, this);
        }

        public ListTester For(ListLocator childLocator)
        {
            childLocator.Append(locator);
            return new ListTester(childLocator, this);
        }

        public TableTester For(TableLocator childLocator)
        {
            childLocator.Append(locator);
            return new TableTester(childLocator, this);
        }

        public RadioButtonTester For(RadioButtonLocator childLocator)
        {
            childLocator.Append(locator);
            return new RadioButtonTester(childLocator, this);
        }

        public CheckBoxTester For(CheckBoxLocator childLocator)
        {
            childLocator.Append(locator);
            return new CheckBoxTester(childLocator, this);
        }

        public ImageTester For(ImageLocator childLocator)
        {
            childLocator.Append(locator);
            return new ImageTester(childLocator, this);
        }

        #endregion
    }
}
